import * as crypto from 'crypto-js';
import {pinyin} from "pinyin-pro";

/**
 * 数字金额化处理
 * number：要格式化的数字
 * decimals：保留几位小数
 * dec_point：小数点符号
 * thousands_sep：千分位符号
 **/
export function moneyFormat(number: any, decimals: number, decPoint: string, thousandsSep: string): string {
    number = (number + '').replace(/[^0-9+-Ee.]/g, '')
    let n = !isFinite(+number) ? 0 : +number
    let prec = !isFinite(+decimals) ? 2 : Math.abs(decimals)
    let sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep
    let dec = (typeof decPoint === 'undefined') ? '.' : decPoint
    let s: string[] = []
    let toFixedFix = function (n: number, prec: number) {
        let k = Math.pow(10, prec)
        return '' + Math.ceil(n * k) / k
    }
    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.')
    let re = /(-?\d+)(\d{3})/
    while (re.test(s[0])) {
        s[0] = s[0].replace(re, '$1' + sep + '$2')
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || ''
        s[1] += new Array(prec - s[1].length + 1).join('0')
    }
    return s.join(dec)
}

/**
 * 保留两位小数
 * number：要格式化的数字
 **/
export function fix2(number: string) {
    return parseFloat(number).toFixed(2)
}

/**
 * 隐藏金额
 **/
export function hideMoneyFormat() {
    return "*****"
}

/**
 * 除百处理
 * number：要格式化的数字
 * decimals：保留几位小数
 **/
export function percent(number: string, decimals: number): string {
    number = (number + '').replace(/[^0-9+-Ee.]/g, '')
    let n = !isFinite(+number) ? 0 : +number
    return (n / 100).toFixed(decimals)
}

/**
 * 递归处理 cascader 数据
 * key：关键字
 * nodes：列表
 * idx：开始层级
 * currentIdx：当前层级
 * path：结果
 **/
export function findPathByLeafId(key: any, nodes: any, idx: any, currentIdx: any, path: any): any {
    if (path === undefined) {
        path = []
    }
    if (currentIdx === undefined) {
        currentIdx = 0
    }
    for (let i = 0; i < nodes.length; i++) {
        let tmpPath = path.concat()
        tmpPath.push(nodes[i].value)
        if (key === nodes[i].value && currentIdx >= idx) {
            return tmpPath
        }
        if (nodes[i].children) {
            let findResult = findPathByLeafId(key, nodes[i].children, idx, currentIdx + 1, tmpPath)
            if (findResult) {
                return findResult
            }
        }
    }
}

/**
 * 将十六进制颜色转为rgba()
 * colorStr：关键字
 * opacity：透明度
 **/
export function toRGB(colorStr: string, opacity: number): string {
    if (typeof opacity === 'undefined' || opacity < 0 || opacity > 1) {
        opacity = 1
    }
    if (colorStr == null || colorStr == '') {
        return '#FFFFFF';
    }
    let color = colorStr.toLowerCase()
    let pattern = /^#([0-9|a-f]{3}|[0-9|a-f]{6})$/
    if (color && pattern.test(color)) {
        if (color.length === 4) {
            // 将三位转换为六位
            color = '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3]
        }
        // 处理六位的颜色值
        let colorNew = []
        for (let i = 1; i < 7; i += 2) {
            colorNew.push(parseInt('0x' + color.slice(i, i + 2)))
        }
        return 'rgba(' + colorNew.join(',') + ',' + opacity + ')'
    }
    return colorStr
}

/**
 * 随机数
 */
export function randomNumber(): number {
    return Math.random() * 100000
}

/**
 * 随机key
 */
export function randomKey(): string {
    return new Date().getTime() + (Math.random() * 1000).toFixed(0)
}

/**
 * 生成随机字符串
 * @param length
 */
export function generateRandomString(length: number): string {
    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let randomString = '';
    for (let i = 0; i < length; i++) {
        const randomIndex = Math.floor(Math.random() * characters.length);
        randomString += characters.charAt(randomIndex);
    }
    return randomString;
}

/**
 * let FormData convert to json Object
 * @param formData
 */
export function getObjectFromFormData(formData: FormData): any {
    const jsonObject: { [key: string]: any } = {};
    for (const [key, value] of formData.entries()) {
        // 检查是否存在同名的键
        if (jsonObject[key] !== undefined) {
            // 如果存在,则将值转换为数组
            if (!Array.isArray(jsonObject[key])) {
                jsonObject[key] = [jsonObject[key]];
            }
            jsonObject[key].push(value);
        } else {
            jsonObject[key] = value;
        }
    }
    return jsonObject;
}

/**
 * 拼接参数生成签名
 * @param obj
 */
export function buildParamsSignStr(obj: { [key: string]: any }): string {
    const sortedKeys = Object.keys(obj).sort((a, b) => a.localeCompare(b, 'en', {numeric: true}));
    const sortedObject: { [key: string]: any } = {};
    const copyObj = JSON.parse(JSON.stringify(obj));
    sortedKeys.forEach(key => {
        sortedObject[key] = copyObj[key];
    });
    let str = "";
    for (const key in sortedObject) {
        if (key == 'sign') continue;
        if (
            key == 'file'
            || typeof sortedObject[key] == 'undefined'
            || sortedObject[key] === ''
            || sortedObject[key] === null
            || sortedObject[key]?.length === 0
        ) {
            continue;
        }
        if (Array.isArray(sortedObject[key])) {
            for (const i in sortedObject[key]) {
                if (typeof sortedObject[key][i] === 'object') {
                    sortedObject[key][i] = crypto.SHA1(JSON.stringify(sortedObject[key][i])).toString();
                }
            }
            sortedObject[key].sort((a: number, b: number) => {
                if (a === b) {
                    return 0;
                }
                return a < b ? -1 : 1;
            });
            sortedObject[key].reverse();
        }
        str += key + "=" + sortedObject[key] + "&";
    }
    str = str.replace(/^&+|&+$/g, '');
    const _str = str + "with=" + import.meta.env.VITE_APP_KEY;
    return crypto.SHA1(_str).toString()
}

/**
 * 解析出文件名
 * @param url
 */
export function extractFileNameFromUrl(url: string): string | null {
    try {
        // 解析 URL
        const parsedUrl = new URL(url);

        // 获取路径部分并移除开头的斜杠
        let pathname = parsedUrl.pathname.slice(1);

        // 如果路径以斜杠结尾，则去掉末尾的斜杠
        if (pathname.endsWith('/')) {
            pathname = pathname.slice(0, -1);
        }

        // 分割路径得到文件名（含扩展名）
        const pathSegments = pathname.split('/');
        const fileNameWithExt = pathSegments[pathSegments.length - 1];

        // 检查是否包含扩展名，并去除扩展名
        const dotIndex = fileNameWithExt.lastIndexOf('.');
        const fileName = dotIndex !== -1 ? fileNameWithExt.substring(0, dotIndex) : fileNameWithExt;

        return fileName;
    } catch (error) {
        console.error('Invalid URL:', error);
        return null;
    }
}

/**
 * 将Base64转blob格式
 * @param base64
 * @param mimeType
 */
export function base64ToBlob(base64: string, mimeType: string) {
    // 将Base64编码的字符串转换为Uint8Array
    const byteCharacters = atob(base64);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
        byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);

    // 创建Blob对象
    return new Blob([byteArray], {type: mimeType});
}

/**
 * 判断字符串是否包含链接地址，并且替换其中的链接标签
 * @param text
 */
export function processLinks(text: string): string {
    // 匹配包含http/https或直接以www开头的链接
    const urlRegex = /((https?:\/\/|www\.)[^\s]+)/g;
    return text.replace(urlRegex, (match) => {
        let url = match;
        if (!url.startsWith('http')) {
            url = 'https://' + url; // 为无协议链接添加默认https
        }
        return `<a href="${url}" target="_blank">${match}</a>`;
    });
}

/**
 * 获取第一字符,如果是字母则转为大写否则标记为#
 * @param text
 */
export function getFirstLetter(text: string): string {
    const _py = pinyin(text, {pattern: 'first', toneType: 'none', type: "array"});
    let _return = "#";
    if (_py.length > 0) {
        _return = /[A-Za-z]$/.test(_py[0]) ? _py[0].toUpperCase() : '#';
    }
    return _return;
}


/**
 * 计算显示日期时间格式
 * 若是当前年时间则返回 m-d H:i
 * 否则返回Y-m-d H:i
 * @param dateTimeString
 * @param replaceTag
 */
export function formatDateTimeStyleOne(dateTimeString: string, replaceTag: string): string {
    const currentYear = new Date().getFullYear();
    const dateTime = new Date(dateTimeString);

    if (typeof replaceTag == "undefined") {
        replaceTag = '/'
    }
    if (dateTime.getFullYear() === currentYear) {
        const month = String(dateTime.getMonth() + 1).padStart(2, '0');
        const day = String(dateTime.getDate()).padStart(2, '0');
        const hour = String(dateTime.getHours()).padStart(2, '0');
        const minute = String(dateTime.getMinutes()).padStart(2, '0');

        return `${month}${replaceTag}${day} ${hour}:${minute}`;
    } else {
        const year = String(dateTime.getFullYear());
        const month = String(dateTime.getMonth() + 1).padStart(2, '0');
        const day = String(dateTime.getDate()).padStart(2, '0');
        const hour = String(dateTime.getHours()).padStart(2, '0');
        const minute = String(dateTime.getMinutes()).padStart(2, '0');

        return `${year}${replaceTag}${month}${replaceTag}${day} ${hour}:${minute}`;
    }
}

/**
 * 检查密码强度
 * @param password
 */
export function checkPasswordStrong(password: string): number {
    let strength = 0;
    if (password.length >= 8) strength++; // 长度至少8个字符开始计算强度
    else return strength;
    if (/[0-9]/.test(password)) strength++; // 包含数字
    if (/[a-z]/.test(password)) strength++; // 包含小写字母
    if (/[A-Z]/.test(password)) strength++; // 包含大写字母
    if (/[^a-zA-Z0-9]/.test(password)) strength++; // 包含特殊字符
    return strength;
}
